package com.xp.tinyurl.schedule;

import com.xp.tinyurl.model.Statistics;
import com.xp.tinyurl.common.cache.ShorterUrlCountCache;
import com.xp.tinyurl.model.Register;
import com.xp.tinyurl.service.AppRegisterService;
import com.xp.tinyurl.service.StatisticsService;
import org.apache.commons.lang3.BooleanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * 统计当前时间前一分钟的接口调用次数及成功转换次数
 *
 * @author  (xp)
 **/
@Service
public class ShortLinkApiStatisticJob {
    /**
     * 常量一分钟
     */
    private static final int ONE_MINUTE = 60 * 1000;
    /**
     * 分页查询每页最值
     */
    private static final int MAX_PER_PAGE = 50;

    @Autowired
    private AppRegisterService appRegisterService;

    @Autowired
    private StatisticsService statisticsService;

    @Autowired
    private ShorterUrlCountCache shorterUrlCountCache;

    public Object handleJavaTask() {
        DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("yyyyMMddHHmm");
        long currentTimeMillis = System.currentTimeMillis();
        long currentTime = currentTimeMillis - currentTimeMillis % ONE_MINUTE;

        // 上一次统计时间
        Long lastStatisticsTime = shorterUrlCountCache.getLastStatisticsTime();
        if (lastStatisticsTime == null) {
            // 统计上一分钟的数据
            long preMinute = currentTime - ONE_MINUTE;
            shorterUrlCountCache.cacheLastStatisticsTime(preMinute);
            // preMinute这一分钟的还没统计
            lastStatisticsTime = preMinute - ONE_MINUTE;
        }

        List<String> appKeys = findAllActiveAppKeys();
        if (!appKeys.isEmpty()) {
            // 统计该时间段内所有appkey
            List<Statistics> statisticsList = new ArrayList<>();

            // 需要统计的分钟数，统计当前时间的前两分钟以前的数据，如果是统计前一分钟的，可能会导致有些成功次数没统计到
            int needStatisticsTimes = (int) (currentTime - ONE_MINUTE * 2 - lastStatisticsTime) / ONE_MINUTE;
            for (String appKey : appKeys) {
                for (int i = 1; i < needStatisticsTimes + 1; i++) {
                    Instant instant = Instant.ofEpochMilli(lastStatisticsTime + i * ONE_MINUTE);
                    ZoneId zone = ZoneId.systemDefault();
                    String statisticsTime = dateFormat.format(LocalDateTime.ofInstant(instant, zone));
                    Statistics statistics = new Statistics();
                    statistics.setAppKey(appKey);
                    statistics.setStatisticsTime(new Date(lastStatisticsTime + i * ONE_MINUTE));
                    statistics.setTotal((int) shorterUrlCountCache.getTotalCountMinute(appKey, statisticsTime));
                    statistics.setSucceed((int) shorterUrlCountCache.getSuccessCountMinute(appKey, statisticsTime));
                    statisticsList.add(statistics);
                }
            }

            statisticsService.persistentByMinute(statisticsList);
        }

        shorterUrlCountCache.cacheLastStatisticsTime(currentTime - ONE_MINUTE * 2);

        return "ok";
    }

    private List<String> findAllActiveAppKeys() {
        List<String> appKeys = new ArrayList<>();

        Integer total = appRegisterService.getPageListCount(new HashMap<>(0));
        for (int i = 0; i <= total / MAX_PER_PAGE; i++) {
            Map<String, Object> map = new HashMap<>(2);
            map.put("pageSize", MAX_PER_PAGE);
            map.put("startPage", i * MAX_PER_PAGE);
            for (Register register : appRegisterService.getPageList(map)) {
                if (BooleanUtils.isFalse(register.getDeleted())) {
                    appKeys.add(register.getAppKey());
                }
            }
        }
        return appKeys;
    }
}
